package com.hengpeng.itfin.service.account.impl;

import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.hengpeng.common.persist.query.DynamicQuery;
import com.hengpeng.common.util.DateTimeUtil;
import com.hengpeng.itfin.service.ServiceFactory;
import com.hengpeng.itfin.service.account.AccountService;
import com.hengpeng.itfinbase.en.TradeMode;
import com.hengpeng.itfinbase.en.TransType;
import com.hengpeng.itfinbase.persist.Account;
import com.hengpeng.itfinbase.persist.AccountLog;
import com.hengpeng.itfinbase.persist.SystemLog.LogType;

@Lazy
@Service
public class AccountServiceImpl implements AccountService {

    @Autowired
    private ServiceFactory serviceFactory;

    @Override
    public List<Account> getAccounts(Long[] userIds) {
        DynamicQuery query = new DynamicQuery(Account.class);
        query.inArray("userId", userIds);
        return serviceFactory.getPersistService().findByDynamicQuery(Account.class, query);
    }

    @Override
    public Account getAccount(Long userId) {
        DynamicQuery query = new DynamicQuery(Account.class);
        query.eq("userId", userId);
        return serviceFactory.getPersistService().getByDynamicQuery(Account.class, query);
    }


    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void changeAccountMoney(Long userId, Long totalMoney, Long baseMoney, Long interestMoney, Long feeAmt,
            TransType transType, TradeMode tradeMode, String referenceId, String remark) {
        Account account = serviceFactory.getDaoFactory().getAccountDao().getAccountByUserId(userId);
        StringBuffer beforedata = new StringBuffer("交易前数据[userId:");
        beforedata.append(account.getUserId()).append(",").append("baseMoney:").append(account.getBaseMoney())
                .append(",").append("FreezeMoney:").append(account.getFreezeMoney()).append("]");

        Long beforeBaseMoney = account.getBaseMoney();// 保留交易前数据
        /**
         * 交易金额
         */
        Long trans_BaseMoney = 0l, trans_TotalfillMoney = 0l, trans_TotalIncomeMoney = 0l, trans_BaseMoneyCollect = 0l, trans_InComeMoneyCollect = 0l, trans_TotaldrawMoney = 0l, trans_FreezeMoney = 0l, trans_BaseMoneyRepay = 0l, trans_InterestMoneyRepay = 0l, trans_TotalInvestMoney = 0l, trans_TotalInvestNum = 0l;

        if (tradeMode == TradeMode.ADD) {// 加钱操作
            trans_BaseMoney = totalMoney;
            switch (transType) {
            case IMPREST:// 充值
                trans_TotalfillMoney = totalMoney;// 更新累计充值字段
                break;
            case REPAYMENT:// 标的还款
            case ADDMONEY:// 标的还款(附加利息,投资人收取)
                trans_TotalIncomeMoney = interestMoney;// 更新累计收益金额
                trans_BaseMoneyCollect = -baseMoney;// 更新待收本金金额
                trans_InComeMoneyCollect = -interestMoney;// 更新待收收益金额
                break;
            }
        } else if (tradeMode == TradeMode.SUBTRACT) {// 减钱操作
            trans_BaseMoney = -totalMoney;
            switch (transType) {
            case DRAW:// 提现
                trans_TotaldrawMoney = totalMoney;// 累计提现金额
                trans_FreezeMoney = -totalMoney;// 同时资金解冻
                trans_BaseMoney = trans_BaseMoney - feeAmt;// 提现减去手续
                break;
            case REPAYMENT:// 标的还款
                trans_BaseMoneyRepay = -baseMoney;// 更新待还本金总额
                trans_InterestMoneyRepay = -interestMoney;// 更新待还利息总额
                break;
            case PAYBACK:// 用户偿还垫付
                trans_BaseMoneyRepay = -baseMoney;// 更新待还本金总额
                trans_InterestMoneyRepay = -interestMoney;// 更新待还利息总额
                break;
            }
        } else if (tradeMode == TradeMode.FREEZE) {
            // 冻结操作
            trans_FreezeMoney = totalMoney;
            switch (transType) {
            case INVEST:// 投标
                // 投标时暂时只更新资金表中的冻结金额,累计投资金额,累计投资笔数。
                // 待收本金,待收收益在投标放款的时候进行更新。放款失败或撤标时需要减少累计投资金额,累计投资笔数
                trans_TotalInvestMoney = totalMoney;
                trans_TotalInvestNum = 1l;
                break;
            }
        } else if (tradeMode == TradeMode.UNFREEZE) {// 解冻操作
            trans_FreezeMoney = -totalMoney;
            switch (transType) {
            case CANCLE:// 撤标
                // 撤标流标资金解冻,减少对应累计投资笔数和累计投资额
                trans_TotalInvestMoney = -totalMoney;
                trans_TotalInvestNum = -1l;
                break;
            }
        }
        int i = serviceFactory
                .getDaoFactory()
                .getAccountDao()
                .updateAccount(trans_BaseMoney, trans_FreezeMoney, trans_TotalfillMoney, trans_TotaldrawMoney,
                        trans_TotalInvestMoney, trans_TotalInvestNum, trans_TotalIncomeMoney, trans_BaseMoneyCollect,
                        trans_InComeMoneyCollect, trans_BaseMoneyRepay, trans_InterestMoneyRepay, new Date(),
                        account.getId());
        if (i > 0) {
            /** 添加资金操作日志 */
            AccountLog accountLog = new AccountLog();
            accountLog.setUserId(userId);
            accountLog.setUserName(account.getUserName());
            accountLog.setTrustAccountId(account.getTrustAccountId());
            accountLog.setTransType(transType);
            accountLog.setAccountType(account.getAccountType());
            accountLog.setReferenceId(referenceId);
            accountLog.setMoney(totalMoney);
            accountLog.setTransTime(new Date());
            accountLog.setTradeMode(tradeMode);
            accountLog.setCreateTime(new Date());
            accountLog.setUpdateTime(new Date());
            accountLog.setBaseMoney(beforeBaseMoney);// 交易前本金
            accountLog.setRemnantBaseMoney(account.getBaseMoney() + trans_BaseMoney);// 交易后本金
            accountLog.setRemnantFreezeMoney(account.getFreezeMoney() + trans_FreezeMoney);// 交易后冻结资金
            /**
             * 交易日志写入文件,交易前数据,交易后数据,交易时间
             */
            StringBuffer afterdata = new StringBuffer("交易后数据[userId:");
            afterdata.append(account.getUserId()).append(",").append("baseMoney:").append(account.getBaseMoney() + trans_BaseMoney)
                    .append(",").append("FreezeMoney:").append(account.getFreezeMoney() +trans_FreezeMoney ).append(",")
                    .append("transType:").append(transType.getText()).append(",").append("tradeMode:")
                    .append(tradeMode.getText()).append(",").append("RemnantFreezeMoney : ")
                    .append(account.getFreezeMoney() + trans_FreezeMoney).append(",").append("TransTime: ")
                    .append(DateTimeUtil.formatToStr(new Date(), DateTimeUtil.DATE_FORMAT_YMDHMS)).append("]");
            accountLog.setRemark(beforedata.append("&").append(afterdata).append(",remark:").append(remark).toString());
            serviceFactory.getPersistService().save(accountLog);
        } else {
            serviceFactory.getSystemLogService().addLog(
                    "",
                    "",
                    LogType.SYSTEMERROR,
                    "资金流水添加异常,userid=[" + userId + "],transType=[" + transType + "],tradeMode=[" + tradeMode
                            + "],totalMoney=[" + totalMoney + "],baseMoney=[" + baseMoney + "],interestMoney=["
                            + interestMoney + "],feeAmt=[" + feeAmt + "],referenceId=[" + referenceId + "]");
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void loansChangeAccountMoney(Long userId, Long totalMoney, Long baseMoney, Long interestMoney,
            TransType transType, TradeMode tradeMode, String referenceId, String remark, boolean addTotal) {
        Account account = serviceFactory.getDaoFactory().getAccountDao().getAccountByUserId(userId);
        long newVersion = account.getVersion() + 1;
        StringBuffer beforedata = new StringBuffer("交易前数据[userId:");
        beforedata.append(account.getUserId()).append(",").append("baseMoney:").append(account.getBaseMoney())
                .append(",").append("FreezeMoney:").append(account.getFreezeMoney()).append("]");

        Long beforeBaseMoney = account.getBaseMoney();// 保留交易前数据
        Long trans_BaseMoney = 0l, trans_TotalfillMoney = 0l, trans_TotalIncomeMoney = 0l, trans_BaseMoneyCollect = 0l, trans_InComeMoneyCollect = 0l, trans_TotaldrawMoney = 0l, trans_FreezeMoney = 0l, trans_BaseMoneyRepay = 0l, trans_InterestMoneyRepay = 0l, trans_TotalInvestMoney = 0l, trans_TotalInvestNum = 0l;
        switch (tradeMode) {
        case ADD:
            trans_BaseMoney = totalMoney;// 加钱操作
            if (transType == TransType.LOAN) {
                if (addTotal) {
                    // 借款人加钱，需要更新待还本金和利息
                    trans_BaseMoneyRepay = baseMoney;// 更新待还本金总额
                    trans_InterestMoneyRepay = interestMoney;// 更新待还利息总额
                }
            }
            break;
        case SUBTRACT:
            trans_BaseMoney = -totalMoney;// 减钱操作
            if (transType == TransType.LOAN) {
                trans_FreezeMoney = -totalMoney;// 解冻
                if (addTotal) {
                    // 投资人转出资金，需要更新待收时本金和待收收益
                    trans_BaseMoneyCollect = baseMoney;// 更新待收本金金额
                    trans_InComeMoneyCollect = interestMoney;// 更新待收收益金额
                }
            }
            break;
        case FREEZE:
            // 冻结操作
            trans_FreezeMoney = totalMoney;
            break;
        case UNFREEZE:
            // 解冻操作
            trans_FreezeMoney = -totalMoney;
            break;
        }
        int i = serviceFactory
                .getDaoFactory()
                .getAccountDao()
                .updateAccount(trans_BaseMoney, trans_FreezeMoney, trans_TotalfillMoney, trans_TotaldrawMoney,
                        trans_TotalInvestMoney, trans_TotalInvestNum, trans_TotalIncomeMoney, trans_BaseMoneyCollect,
                        trans_InComeMoneyCollect, trans_BaseMoneyRepay, trans_InterestMoneyRepay, new Date(),
                        account.getId());
        if (i > 0) {
            /** 添加资金操作日志 */
            AccountLog accountLog = new AccountLog();
            accountLog.setUserId(userId);
            accountLog.setUserName(account.getUserName());
            accountLog.setTrustAccountId(account.getTrustAccountId());
            accountLog.setAccountType(account.getAccountType());
            accountLog.setTransType(transType);
            accountLog.setReferenceId(referenceId);
            accountLog.setMoney(totalMoney);
            accountLog.setTransTime(new Date());
            accountLog.setTradeMode(tradeMode);
            accountLog.setCreateTime(new Date());
            accountLog.setUpdateTime(new Date());
            accountLog.setBaseMoney(beforeBaseMoney);// 交易前本金
            accountLog.setRemnantBaseMoney(account.getBaseMoney() + trans_BaseMoney);// 交易后本金
            accountLog.setRemnantFreezeMoney(account.getFreezeMoney() + trans_FreezeMoney);// 交易后冻结资金
            /**
             * 交易日志写入文件,交易前数据,交易后数据,交易时间
             */
            StringBuffer afterdata = new StringBuffer("交易后数据[userId:");
            afterdata.append(account.getUserId()).append(",").append("baseMoney:").append(account.getBaseMoney())
                    .append(",").append("FreezeMoney:").append(account.getFreezeMoney()).append(",")
                    .append("transType:").append(transType.getText()).append(",").append("tradeMode:")
                    .append(tradeMode.getText()).append(",").append("RemnantFreezeMoney : ")
                    .append(account.getFreezeMoney()).append(",").append("TransTime: ")
                    .append(DateTimeUtil.formatToStr(new Date(), DateTimeUtil.DATE_FORMAT_YMDHMS)).append("]");
            accountLog.setRemark(beforedata.append("&").append(afterdata).append(",remark:").append(remark).toString());
            serviceFactory.getPersistService().save(accountLog);
        } else {
            serviceFactory.getSystemLogService().addLog(
                    "",
                    "",
                    LogType.SYSTEMERROR,
                    "资金流水添加异常,userid=[" + userId + "],transType=[" + transType + "],tradeMode=[" + tradeMode
                            + "],totalMoney=[" + totalMoney + "],baseMoney=[" + baseMoney + "],interestMoney=["
                            + interestMoney + "],referenceId=[" + referenceId + "]");
            // throw new RuntimeException("资金流水添加异常");
        }
    }
}
